#include "TcpManager.h"
#include "ReadFile.h"

#include <QFileInfo>

TcpManager::TcpManager(QObject *parent)
    : QObject{parent}
{
    initConfig();
    m_Timer = new QTimer(this);
    connect(m_Timer,&QTimer::timeout,this,&TcpManager::handleDisconnected);
    m_Tcpsocket = new QTcpSocket(this);
    connect(m_Tcpsocket, &QTcpSocket::readyRead, this, &TcpManager::onReadyRead);
    connect(m_Tcpsocket,&QTcpSocket::disconnected,this,[=](){
        m_Timer->start(3000);
    });
    connect(m_Tcpsocket, &QTcpSocket::connected, this, [=]() {
        if(m_Timer->isActive()) m_Timer->stop();
        m_Local_IP = m_Tcpsocket->localAddress().toString();
        qDebug() << "Connected to server! Local IP Adress:" << m_Local_IP;
    });
    m_Tcpsocket->connectToHost(m_server_IP,m_Server_Port);
}

void TcpManager::initConfig()
{
    Tcp_Config config = ReadFile::getIntance()->readTcpConfigFile(":/configFile/Config.ini");
    m_server_IP = config.serverIP;
    m_Server_Port = config.serverPort;
    qWarning() << "Server IP Adress And Port Config:" << m_server_IP << m_Server_Port;
}

void TcpManager::sendMessage(MessagePacket &message)
{
    QByteArray tempBuffer;
    QDataStream tempStream(&tempBuffer, QIODevice::WriteOnly);
    tempStream.setByteOrder(QDataStream::LittleEndian);
    tempStream << message; // 直接使用重载的 `<<` 操作符

    message.dataSize = tempBuffer.size();

    QByteArray buffer;
    QDataStream stream(&buffer,QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::LittleEndian);
    stream << message;

    qint64 bytesSent = m_Tcpsocket->write(buffer);
    m_Tcpsocket->flush(); // 确保立即发送

    qDebug() << "dataSize的大小" << message.dataSize;
    qDebug() << "发送了" << bytesSent << "字节的数据";
}

void TcpManager::sendFile(FilePacket &data)
{
    QByteArray tempBuffer;
    QDataStream tempStream(&tempBuffer, QIODevice::WriteOnly);
    tempStream.setByteOrder(QDataStream::LittleEndian);
    tempStream << data; // 直接使用重载的 `<<` 操作符

    data.dataSize = tempBuffer.size();

    QByteArray buffer;
    QDataStream stream(&buffer,QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::LittleEndian);
    stream << data;

    qint64 bytesSent = m_Tcpsocket->write(buffer);
    m_Tcpsocket->flush(); // 确保立即发送

    qDebug() << "dataSize的大小" << data.dataSize;
    qDebug() << "发送了" << bytesSent << "字节的数据";
}

void TcpManager::onReadyRead()
{
#if 0
    qWarning() << "new message";
    m_Buffer.append(m_Tcpsocket->readAll());
    if(m_Buffer.size() < 8) return;

    Stu_Head headData;
    memcpy(&headData,m_Buffer.data(),8);
    //qWarning() << m_Buffer.toHex();
    if(m_Buffer.size() < headData.dataSize) return;
    QByteArray data = m_Buffer.mid(0,headData.dataSize);
    m_Buffer.remove(0,headData.dataSize);
    processData(data,headData.infoType);

    m_Buffer.append(m_Tcpsocket->readAll());

#else

     m_Buffer.append(m_Tcpsocket->readAll());
    // 用循环，确保一次接收到多个包也能处理
    while (true) {
        // 先检查是否有头部（8字节）
        if (m_Buffer.size() < 8) {
            qDebug() << "数据不足8字节，等待更多数据，当前缓存大小:" << m_Buffer.size();
            return; // 等待更多数据
        }

        Stu_Head headData;
        memcpy(&headData, m_Buffer.data(), 8);
        qDebug() << "读取到包头，dataSize:" << headData.dataSize << " infoType:" << headData.infoType;

        // 判断当前缓存数据是否足够构成一个完整包（头部+数据体）
        if (m_Buffer.size() < headData.dataSize) {
            qDebug() << "缓存数据(" << m_Buffer.size() << "字节)不足一个完整包(" << headData.dataSize << "字节)，等待更多数据";
            return;
        }

        // 数据完整，可以提取一个完整包
        QByteArray fullPacket = m_Buffer.left(headData.dataSize);
        m_Buffer.remove(0, headData.dataSize);
        qDebug() << "提取了完整包，大小:" << fullPacket.size() << "字节, 将要处理的类型:" << headData.infoType;

        // 调用处理函数处理该包
        processData(fullPacket, headData.infoType);
    }

#endif
}

void TcpManager::handleDisconnected()
{
    qWarning() << "Reconnect To Server";
    m_Tcpsocket->connectToHost(m_server_IP,m_Server_Port);
}

void TcpManager::slot_SendMessage(QString &targetIP, QString &messageStr)
{
    MessagePacket messagePacket;
    messagePacket.sourceAddress = m_Local_IP;
    messagePacket.targetAddress = targetIP;
    messagePacket.messageData = messageStr;

    sendMessage(messagePacket);
}

void TcpManager::slot_SendFile(QString &targetIP, QString filePath)
{
    FilePacket filePacket;
    filePacket.sourceAddress = m_Local_IP;
    filePacket.targetAddress = targetIP;
    QFileInfo fileInfo(filePath);
    filePacket.fileName = fileInfo.fileName();
    filePacket.fileData = ReadFile::getIntance()->readFile(filePath);

    qWarning() << "File Name:" << filePacket.fileName;
    sendFile(filePacket);
}

void TcpManager::processData(QByteArray &msgData, int type)
{
    QDataStream stream(msgData);
    stream.setByteOrder(QDataStream::LittleEndian);
    switch (type)
    {
    case NewClientType:
    {
        NewClient data;
        stream >> data;
        emit signal_NewClient(data);
        break;
    }
    case FilePacketType:
    {
        FilePacket data;
        stream >> data;
        emit signal_FilePacket(data);
        break;
    }
    case MessagePacketType:
    {
        MessagePacket data;
        stream >> data;
        emit signal_MessagePacket(data);
        break;
    }
    default:
        qWarning() << "未知消息类型";
        break;
    }
}
